//-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-· 属性修饰工具类型 ·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·

// 属性修饰工具类型中，访问性修饰工具类型包括三位：? 、- 、 readonly 、 +
type PartialCus<T> = {
  [P in keyof T]?: T[P];
};

type Required1<T> = {
  [P in keyof T]-?: T[P];
};
type Required2<T> = {
  [P in keyof T]+?: T[P];
};
// -? 如果T中的属性有?的就将?移除。
// +? 给新的类型属性添加上?

type Readonly1<T> = {
  -readonly [P in keyof T]: T[P];
};

type Readonly2<T> = {
  +readonly [P in keyof T]: T[P];
};

type Record1<K extends keyof any, T> = {
  [P in K]: T;
};
/**
 * K extends keyof any ==> K可以是联合类型也可以是单个类型
 * T ==> 是属性值的类型
 */

type Record3 = Record<string, unknown>;
type Record4 = Record1<string, any>;

let newAsd: Record<string, any> = {
  aaa: 1,
  bb: 2,
  ccc: "333",
};
newAsd["ddd"] = { aa: 222 };

type Dictionary<T> = {
  [index: string]: T;
};
//-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-· 结构处理工具类型 ·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·
//  Pick Omit
type Pick1<T, K extends keyof T> = {
  [P in K]: T[P];
};

type Omit1<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
// pick 从一个对象中挑出一些属性形成一个新的对象
interface Foo {
  name: string;
  age: number;
  job: JobUnionType;
}
type JobUnionType = Pick1<Foo, "age" | "name">;

/**
 * Omit 将对象中的一些属性剔除
 * 是基于pick实现的 -- 反向工具类型基于正向工具类型实现
 * Exclude<A, B> -- 提出A中不存在于B的部分
 */
type JobExcludeType = Omit<Foo, "age">;

type Omit2<T, K> = Pick1<T, Exclude<keyof T, K>>;

// -·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·集合工具类型·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·
// 交集 Extract
type BingJi<T, U> = T extends U ? T : never; // 内部实现
type AExtractB = Extract<1 | 2 | 3, 1 | 2>;
// 差集
type ChaJi<T, U> = T extends U ? never : T;
type AExcludeB = Exclude<1 | 2 | 3, 1 | 2>;
// 并集
type Concurrence<A, B> = A | B;
// 补集 基于差集实现，只需要约束U 是T的子集
type BuJi<T, U extends T> = ChaJi<T, U>;
type aaa = BuJi<1 | 2 | 3, 1 | 2>;

// -·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·模式匹配工具类型·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·
